#include <WinSock2.h>  // 引入套接字编程库
#include <iostream>
#include <string>
#include <cstring>

#pragma warning(disable:4996)  // 屏蔽错误
#pragma comment(lib, "ws2_32.lib")  // 固定用法

// 服务器公网ip 服务器端口号
std::string serverIp = "43.143.4.250";  // IPV4
std::uint16_t serverPort = 8080;

int main()
{
	WSADATA WSAData;  // win 初始化
	if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
	{
		//WSACleanup();
		std::cout << "初始化失败！" << std::endl;
		return -1;
	}

	SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);  // 创建套接字
	if (sock < 0)
	{
		std::cout << "套接字创建失败!" << std::endl;
		exit(-1);
	}

	// 客户端不需要与本地绑定bind，现在初始化服务器端的套接字结构，方便发送数据和接收数据
	struct sockaddr_in server;
	memset(&server, 0, sizeof server);  // 清零
	server.sin_family = AF_INET;  // 协议家族
	server.sin_port = htons(serverPort);  // 转为网络字节序哦
	server.sin_addr.S_un.S_addr = inet_addr(serverIp.c_str());  // 点分式转化为整数，然后在转化为网络字节序

	char buffer[1024];
	// 发送内容
	while(true)
	{
		std::cout << "win客户端输入# ";
		std::string message;
		std::getline(std::cin, message);

		if (message == "quit") break;
		
		// 向服务器发送消息，客户端第一次发送自动绑定ip和port
		sendto(sock, message.c_str(), (int)message.size(), 0, (struct sockaddr*)&server, sizeof server);

		// 服务器向客户端发送消息：--双向sock套接字--
		struct sockaddr_in _server;
		int tmp = sizeof _server;
		int s = recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&_server, &tmp);  // 存在问题
		if (s > 0)
		{
			buffer[s] = '\0';
			std::cout << "server echo# " << buffer << std::endl;
		}
	}

	closesocket(sock);
	WSACleanup();  // 结束
	return 0;
}